package ru.arriah.servicedesk.web.leadExecutor.action;

import java.io.IOException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;

import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ru.arriah.common.web.action.ActionMapping;
import ru.arriah.common.web.action.DumbAction;
import ru.arriah.servicedesk.bean.EmployeeBean;
import ru.arriah.servicedesk.bean.MailTemplateBean;
import ru.arriah.servicedesk.bean.RequestBean;
import ru.arriah.servicedesk.bean.RequestPriorityBean;
import ru.arriah.servicedesk.bean.TaskBean;
import ru.arriah.servicedesk.bean.error.TaskFormErrorBean;
import ru.arriah.servicedesk.ejb.EmployeeManagerLocalHome;
import ru.arriah.servicedesk.ejb.EmployeeManagerLocalObject;
import ru.arriah.servicedesk.ejb.RequestManagerLocalHome;
import ru.arriah.servicedesk.ejb.RequestManagerLocalObject;
import ru.arriah.servicedesk.ejb.UtilityManagerLocalHome;
import ru.arriah.servicedesk.ejb.UtilityManagerLocalObject;
import ru.arriah.servicedesk.help.MailSender;
import ru.arriah.servicedesk.help.Utils;
import ru.arriah.servicedesk.web.commonaction.exception.InternalException;
import ru.arriah.servicedesk.web.commonaction.exception.PrivilegesException;


public class ProcessTaskFormAction extends DumbAction {
  
  protected RequestManagerLocalHome requestManagerHome;
  protected TaskFormErrorBean taskFormErrorBean;
  protected EmployeeManagerLocalHome employeeManagerLocalHome;
  protected UtilityManagerLocalHome utilityManagerHome;
  
  public ProcessTaskFormAction() throws NamingException {
    super();
    
    requestManagerHome = 
      Utils.getRequestManagerHomeInterface();
     
    employeeManagerLocalHome = 
      Utils.getEmployeeManagerHomeInterface();
    
    utilityManagerHome = 
       Utils.getUtilityManagerHomeInterface();
  }
  
  
  /**
   * Validate request
   * @param taskBean
   * @return boolean
   * @throws InternalException
   */
  public boolean isValid(TaskBean taskBean, int leadexecutorId) throws InternalException {
    try {
      boolean result = true;
      taskFormErrorBean = new TaskFormErrorBean();
    
    if (taskBean.getEmployeeId() == 0) {
      taskFormErrorBean.setExecutor(config.getProperty("ERROR.TASKFORM.EXECUTOR"));
      result = false;
    }
    
    if (taskBean.isEmpty(taskBean.getName())) {
       taskFormErrorBean.setName(config.getProperty("ERROR.TASKFORM.NAME"));
       result = false;
    }
    
    if (taskBean.getPriority()==0) {
      taskFormErrorBean.setPriority(config.getProperty("ERROR.TASKFORM.PRIORITY"));
      result = false;
    }
    
    if ((taskBean.getText() == null) || (taskBean.getText().equals(""))) {
      taskFormErrorBean.setTaskText(config.getProperty("ERROR.TASKFORM.TEXT"));
      result = false;
    }
    
//    if (taskBean.getStatusId() == 0) {
//      taskFormErrorBean.setStatus(config.getProperty("ERROR.TASKFORM.STATUS"));
//      result = false;
//    }
    
    if (taskBean.getStartDate() == null) {
      taskFormErrorBean.setStartDate(config.getProperty("ERROR.TASKFORM.STARTDATE"));
      result = false;
    }
    
    if (taskBean.getApproxEndDate() == null) {
      taskFormErrorBean.setEndDate(config.getProperty("ERROR.TASKFORM.ENDDATE"));
      result = false;
    }
    
    /**
     * Дата завершения должна быть позже даты начала
     * 
     */
    
    if ((taskBean.getStartDate() != null) && (taskBean.getApproxEndDate() != null)) {
      if (taskBean.getStartDate().after(taskBean.getApproxEndDate())) {
        taskFormErrorBean.setStartDate(config.getProperty("ERROR.TASKFORM.STARTAFTEREND"));
        taskFormErrorBean.setApproxEndDate(config.getProperty("ERROR.TASKFORM.STARTAFTEREND"));
        result = false;
      } else {
        RequestManagerLocalObject requestManager = 
          requestManagerHome.create();
        
        RequestBean requestBean = 
          requestManager.selectRequest(taskBean.getRequestId());                    
        requestManager.remove();
        
        /**
         * и не выходить за границы выполнения заявки
         */ 
      
        if (requestBean.getApproxEndDate().before(taskBean.getApproxEndDate())) {
          taskFormErrorBean.setEndDate(
            String.format(
              config.getProperty("ERROR.TASKFORM.T-ENDAFTERR-END"), 
              requestBean.getApproxEndDate()
            )
          );
          result = false;
        }
        
        if (requestBean.getRegistrationDate().after(taskBean.getStartDate()) && 
           !sameDay(requestBean.getRegistrationDate(), taskBean.getStartDate())
        ) {
          taskFormErrorBean.setStartDate(
            String.format(
              config.getProperty("ERROR.TASKFORM.R-STARTAFTERT-START"),
              requestBean.getRegistrationDate()
            )
          );  
          result = false;
        }
      }
    }
    
    
    //is subordinate valid ?    
    EmployeeManagerLocalObject employeeManager = 
       employeeManagerLocalHome.create();
    Collection<EmployeeBean> subordinates = 
       employeeManager.selectSubordinates(leadexecutorId);
    
    Iterator i = subordinates.iterator();
    boolean isEmployee = false;
    
    while (i.hasNext() && !isEmployee) {
       EmployeeBean employee = (EmployeeBean) i.next();
       if (employee.getId() == taskBean.getEmployeeId())
          isEmployee = true;
    }
    
    if (!isEmployee) {       
       result = false;
    }
    
    return result;
    } catch (Exception e) {
      handleException(e, "isValid");
      throw new InternalException("ErrorMessage.internal");
    }
  }
  
  
  private TaskBean restoreBean(HttpServletRequest request) {
     TaskBean taskBean = new TaskBean();
     
     int requestId = idVal(request.getParameter("request_id"));
     
     DateFormat dateformat = 
          DateFormat.getDateInstance(
             DateFormat.SHORT, 
             new Locale("ru")
          );
     
     taskBean.setEmployeeId(idVal(request.getParameter("employee_id")));
     taskBean.setRequestId(requestId);
     taskBean.setText(request.getParameter("text"));
     taskBean.setPriority(idVal(request.getParameter("priority")));
     taskBean.setName(request.getParameter("name"));
     
     /*
     * ParseException - if the beginning of the specified string cannot be parsed
     */
     
     try {
       taskBean.setStartDate(
         dateformat.parse(request.getParameter("startdate"))
       );
     } catch (Exception e) {}
     
     try {
       taskBean.setApproxEndDate(
         dateformat.parse(request.getParameter("enddate"))
       );
     } catch (Exception e) {}
     
     return taskBean;
  }
    
  
  
  private void sendMail(TaskBean taskBean, String mailTemplateKey) {
     try {      
        UtilityManagerLocalObject utilityManager = 
          utilityManagerHome.create();
        
        EmployeeManagerLocalObject employeeManager = 
           employeeManagerLocalHome.create();
        
        EmployeeBean employeeBean = 
           employeeManager.selectEmployee(taskBean.getEmployeeId());
        
        MailSender mailSender = new MailSender();           
        
        mailSender.setSmtpPort(config.getProperty("SMTP_PORT"));
        mailSender.setHostName(config.getProperty("SMTP_HOST_NAME"));
        mailSender.setFrom(config.getProperty("FROM"));
        mailSender.setCharset("UTF-8");

//Inside ARRIAH LAN authentication not required        
//        mailSender.setAuthentication(
//          config.getProperty("LOGIN"), 
//          config.getProperty("PASSWORD")
//        );
        
        MailTemplateBean mailTemplate = 
          utilityManager.selectMailTemplateByKey(
             mailTemplateKey
          );       
        
        mailSender.setSubject(mailTemplate.getSubject());              
        
        mailSender.setContent(
          String.format(
            mailTemplate.getBody(),
            employeeBean.getFirstName(),
            employeeBean.getLastName(),
            new Date(),
            taskBean.getId(),
            config.getProperty("HOST")
          )
        );       
                       
        mailSender.addRecipient(employeeBean.getEmail());                           
        mailSender.send();
        
        utilityManager.remove();
      } catch (Exception e) {
        handleException(e, "sendMail");       
      }
  }

  
  
  
  
  public String execute(
     ActionMapping actionMapping,
     HttpServletRequest request, 
     HttpServletResponse response
  ) throws IOException, ServletException {
    try {
       
       RequestManagerLocalObject requestManager = 
          requestManagerHome.create();       
       
       int leadExecutorId = Utils.getUserId(request);
       int taskId = idVal(request.getParameter("task_id"));
       int requestId = idVal(request.getParameter("request_id"));
      
       RequestBean requestBean = 
          requestManager.selectRequestDetails(requestId);
       
       if (requestBean.getLeadExecutorId() != leadExecutorId) {
          throw new PrivilegesException();
       }
      
      TaskBean taskBean = this.restoreBean(request);                     
      
      
      if (!isValid(taskBean, leadExecutorId)) {
        EmployeeManagerLocalObject employeeManager = 
          employeeManagerLocalHome.create();
        
        Collection<EmployeeBean> employeesList = 
          employeeManager.selectSubordinates(leadExecutorId);
        
        employeeManager.remove();
        

        Collection<RequestPriorityBean> priorityList = 
          requestManager.selectPriorityList();
          
        request.setAttribute("priorityList", priorityList);        
        request.setAttribute("employeesList", employeesList);
        request.setAttribute("taskBean", taskBean);
        request.setAttribute("error", taskFormErrorBean);
        request.setAttribute("action", actionMapping.getActionName());
        
        addErrorMessage(
           request, 
           config.getProperty("ERROR.TASKTFORM_FIELDS_INVALID")
        );
                 
        return actionMapping.getFailureTarget();
      }
                        
      
      Action action = Action.valueOf(actionMapping.getActionName());

      switch (action) {
         case processAddTaskForm:
            taskBean.setStatusId(1);  //active status
            requestManager.addTask(taskBean);
            
            if (request.getParameter("donotify") != null) {                  
               sendMail(taskBean, "NEW_REQUEST_TO_EXECUTOR");
            }
            
            addInfMessage(request, config.getProperty("INF.TASK_ADDED"));
            break;
            
         case processEditTaskForm:
            TaskBean oldTask = requestManager.selectTask(taskId);
            taskBean.setStatusId(oldTask.getStatusId());
            
            taskBean.setId(taskId);
            requestManager.updateTask(taskBean);        
            
            if (request.getParameter("donotify") != null) {                  
               sendMail(taskBean, "EDIT_REQUEST_TO_EXECUTOR");
            }
            
            addInfMessage(request, config.getProperty("INF.TASK_UPDATED"));
            break;
            
         default:
            throw new RuntimeException("Unsupported action " + action);
      }                               
      
      
      Collection<TaskBean> tasksList = 
        requestManager.selectTasksByRequest(
           taskBean.getRequestId()          
        );
      
      request.setAttribute("tasksList", tasksList);
      request.setAttribute("requestBean", requestBean);
      request.setAttribute("status", "request_lead_executor");
      
      return actionMapping.getSuccessTarget();
    } catch (Exception e) {
      handleException(e, "execute");
      throw new InternalException("ErrorMessage.internal");
    }
  }
}